package com.start.system.user.controller;

import cn.hutool.core.codec.Base64;
import com.start.admin.SystemLoginConfig;
import com.start.admin.entity.StartSysUser;
import com.start.admin.service.StartSysUserService;
import com.start.admin.vo.StartUserInfoVo;
import com.start.common.api.Result;
import com.start.common.details.BaseUserDetail;
import com.start.common.entity.StartBaseMenu;
import com.start.common.entity.StartBaseRole;
import com.start.common.entity.StartBaseUser;
import com.start.common.exceptions.StartBusException;
import com.start.core.annotations.StartLog;
import com.start.core.log.StartLogStore;
import com.start.core.vo.LoginModel;
import com.start.core.vo.UpdateCurrentUserPasswordVo;
import com.start.security.StartTokenTools;
import com.start.security.StartUserPermissionTools;
import com.start.security.annotations.IgnoreAuth;
import com.start.security.annotations.StartUrlDataSecurity;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.web.bind.annotation.*;

import java.util.List;


@RestController
@AllArgsConstructor
@RequestMapping("/user")
public class UserLoginController {

    private static final String LOG_TITLE = "当前用户";
    private final UserDetailsService userDetailsService;

    private final StartSysUserService sysUserService;


    private final StartTokenTools tokenTools;


    private final StartUserPermissionTools userPermissionTools;
    private final StartTokenTools startTokenTools;

    /**
     * 获取登录验证码
     *
     * @return
     */
    @IgnoreAuth
    @StartUrlDataSecurity
    @StartLog(value = LOG_TITLE, action = "获取登录验证码")
    @GetMapping("/getLoginCode")
    public Result<?> getLoginCode() {
        SystemLoginConfig loginConfig = SystemLoginConfig.getInstance();
        return Result.ok(loginConfig.createCaptcha());
    }

    @PostMapping("/login")
    @IgnoreAuth
    @StartUrlDataSecurity
    public Result<?> login(@RequestBody LoginModel loginModel) {
        if (StringUtils.isEmpty(loginModel.getUserName())) throw new StartBusException("用名不能为空");
        loginModel.setUserName(Base64.decodeStr(loginModel.getUserName()));
        if (StringUtils.isEmpty(loginModel.getPassword())) throw new StartBusException("密码不能为空");
        loginModel.setPassword(Base64.decodeStr(loginModel.getPassword()));
        SystemLoginConfig loginConfig = SystemLoginConfig.getInstance();
        loginConfig.checkLogin(loginModel);


        BaseUserDetail userDetails = (BaseUserDetail) userDetailsService.loadUserByUsername(loginModel.getUserName());
        List<StartBaseRole<?>> userRole = userPermissionTools.getUserRole(userDetails);
        if (userRole.isEmpty()) {
            throw new StartBusException("当前账号未指定角色，请联系您的管理员为您分配角色");
        }
        String token = tokenTools.login(userDetails, loginModel.getPassword());
        StartLogStore.getStore().createUserLoginLog(userDetails);
        return Result.ok("登录成功", token);
    }

    @PostMapping("/switchUser")
    @StartLog(value = LOG_TITLE, action = "切换用户")
    public Result<?> switchUser(@RequestBody LoginModel loginModel) {
        if (StringUtils.isEmpty(loginModel.getUserName())) throw new StartBusException("用名不能为空");
        loginModel.setUserName(Base64.decodeStr(loginModel.getUserName()));
        if (StringUtils.isEmpty(loginModel.getPassword())) throw new StartBusException("密码不能为空");
        loginModel.setPassword(Base64.decodeStr(loginModel.getPassword()));
        BaseUserDetail userDetails = (BaseUserDetail) userDetailsService.loadUserByUsername(loginModel.getUserName());
        List<StartBaseRole<?>> userRole = userPermissionTools.getUserRole(userDetails);
        if (userRole.isEmpty()) {
            throw new StartBusException("当前账号【" + loginModel.getUserName() + "】未指定角色，请联系您的管理员为您分配角色");
        }
        String token = tokenTools.login(userDetails, loginModel.getPassword());
        StartLogStore.getStore().createUserLoginLog(userDetails);
        return Result.ok("登录成功", token);
    }

    @StartLog(value = LOG_TITLE, action = "刷新token")
    @PostMapping("/refreshToken")
    public Result<?> refreshToken() {
        return Result.ok(tokenTools.updateCurrentToken());
    }

    @GetMapping("/getUserInfo")
    public Result<?> getUserInfo() {
        BaseUserDetail currentUser = StartTokenTools.getCurrentUser();
        final List<StartBaseRole<?>> userRole = userPermissionTools.getUserRole(currentUser);
        final List<StartBaseMenu<?>> userMenu = userPermissionTools.getUserMenu(currentUser);
        StartUserInfoVo userInfoVo = new StartUserInfoVo(currentUser, userRole, userMenu);
        return Result.ok(userInfoVo);
    }

    @PostMapping("/updateCurrentUserInfo")
    public Result<?> updateCurrentUserInfo(@RequestBody StartSysUser user) {
        BaseUserDetail currentUser = StartTokenTools.getCurrentUser();
        String currentUserToken = startTokenTools.getCurrentUserToken();
        sysUserService.updateUserInfo(currentUser, user);
        BaseUserDetail userDetails = (BaseUserDetail) userDetailsService.loadUserByUsername(currentUser.getUsername());
        tokenTools.updateUserDetailByToken(currentUserToken, userDetails);
        StartBaseUser startBaseUser = userDetails.getStartBaseUser();
        startBaseUser.setUserPwd(null);
        return Result.ok(startBaseUser);
    }


    @StartLog(value = LOG_TITLE, action = "修改当密码")
    @PostMapping("/updateCurrentUserPassword")
    public Result<?> updateCurrentUserPassword(@RequestBody UpdateCurrentUserPasswordVo model) {
        sysUserService.updateCurrentUserPassword(model);
        return Result.ok();
    }


    @IgnoreAuth
    @GetMapping("/loginOut")
    public Result<?> loginOut() {
        BaseUserDetail currentUser = StartTokenTools.getCurrentUser(false);
        StartLogStore.getStore().createUserLoginOutLog(currentUser);
        tokenTools.removeCurrentToken();
        return Result.ok();
    }


}
